def expand_variables(template, var_data, extra_data = {})
  self.class.expand_variables(template, var_data, extra_data)
end

<% if object.kind? -%>
def fetch_resource(resource, self_link, kind)
  self.class.fetch_resource(resource, self_link, kind)
end
<% else # object.kind? -%>
def fetch_resource(resource, self_link)
  self.class.fetch_resource(resource, self_link)
end
<% end # object.kind? -%>

<%= lines(emit_link('async_op_url', async_operation_url(object), false,
                    true)) -%>

def wait_for_operation(response, resource)
<% if object.kind? -%>
<%   op_kind = object.async.operation.kind -%>
  op_result = return_if_object(response, '<%= op_kind -%>')
<% else # object.kind? -%>
  op_result = return_if_object(response)
<% end # object.kind? -%>
  return if op_result.nil?
<%   stat_path = Google::HashUtils.path2navigate(object.async.status.path) -%>
  status = ::Google::HashUtils.navigate(op_result, <%= stat_path -%>)
<%   res_path = Google::HashUtils.path2navigate(object.async.result.path) -%>
<% if object.self_link_query.nil? -%>
<%=
  lines(format(
    [
      [
        'fetch_resource(',
        indent([
          'resource,',
          'URI.parse(::Google::HashUtils.navigate(wait_for_completion(status,',
          indent(['op_result,',
                  'resource),'], 59), # 59 = align with last ( previous line
          # 39 = align with ( previous line
          indent("#{res_path}))#{',' if object.kind?}", 39),
          ("'#{object.kind}'" if object.kind?)
        ].compact, 2),
        ')'
      ],
      [
        'wait_done = wait_for_completion(status, op_result, resource)',
        'fetch_resource(',
        indent([
          'resource,',
          'URI.parse(::Google::HashUtils.navigate(wait_done,',
          # 39 = align with ( previous line
          indent("#{res_path}))#{',' if object.kind?}", 39),
          ("'#{object.kind}'" if object.kind?)
        ].compact, 2),
        ')'
      ]
    ], 2, inside_indent
  ))
-%>
<% else # object.self_link_query.nil? -%>
  wait_for_completion status, op_result, resource
<% obj_kind = object.kind? ? "'#{object.kind}'," : '' -%>
<%=
  lines(format(
    [
      [
        "fetch_wrapped_resource(resource, #{obj_kind}",
        ("'#{object.self_link_query.kind}'," if object.self_link_query.kind?),
        "'#{object.self_link_query.items}')"
      ].join(' '),
      [
        [
         "fetch_wrapped_resource(resource, #{obj_kind}",
         ("'#{object.self_link_query.kind}'," if object.self_link_query.kind?)
        ].join(' '),
        indent([
          "'#{object.self_link_query.items}')"
        ], 23) # 23 = align with ( previous line
      ],
      [
        "fetch_wrapped_resource(resource, #{obj_kind}",
        indent([
          "'#{object.self_link_query.kind}',",
          "'#{object.self_link_query.items}')"
        ], 23) # 31 = align with ( previous line
      ]
    ], 2, inside_indent
  ))
-%>
<% end # object.self_link_query.nil? -%>
end

def wait_for_completion(status, op_result, resource)
<%   op_path = Google::HashUtils.path2navigate(object.async.operation.path) -%>
  op_id = ::Google::HashUtils.navigate(op_result, <%= op_path -%>)
  op_uri = async_op_url(resource, op_id: op_id)
  while status != '<%= object.async.status.complete -%>'
    debug("Waiting for completion of operation #{op_id}")
<%   err_path = Google::HashUtils.path2navigate(object.async.error.path) -%>
<%   err_msg = object.async.error.message -%>
    raise_if_errors op_result, <%= err_path -%>, '<%= err_msg -%>'
    sleep <%= sprintf('%.1f', object.async.operation.wait_ms / 1000.0) %>
<%   allowed_states = object.async.status.allowed -%>
    raise "Invalid result '#{status}' on <%= object.out_name -%>." \
      unless %w[<%= allowed_states.join(' ') -%>].include?(status)
<% if object.kind? -%>
    op_result = fetch_resource(resource, op_uri, '<%= op_kind -%>')
<% else # object.kind? -%>
    op_result = fetch_resource(resource, op_uri)
<% end # object.kind? -%>
    status = ::Google::HashUtils.navigate(op_result, <%= stat_path -%>)
  end
  op_result
end

def raise_if_errors(response, err_path, msg_field)
  self.class.raise_if_errors(response, err_path, msg_field)
end
